package com.wangzhenyu.learn.test.kotlin.reflect

import kotlin.reflect.KClass
import kotlin.reflect.KMutableProperty1
import kotlin.reflect.full.*
import kotlin.reflect.jvm.isAccessible

@Suppress("UNUSED")
object InstanceReflect {

    //获取TestReflect的KClass类
    //还有一种方法，声明一个实例，val hello = Hello() val clazz = hello.javaClass.kotlin
    private var clazz: KClass<TestReflect> = TestReflect::class

    //构造器
    //获取TestReflect所有构造器
    fun go01() {
        clazz.constructors.forEach {
            println(it)
        }
    }

    //获取主构造器
    fun go02() {
        println(clazz.primaryConstructor)
    }

    //调用无参构造器创建实例
    fun go12() {
        val instance = clazz.createInstance()
        println(instance.name)
    }

    //调用主构造函数
    fun go13() {
        val instance = clazz.primaryConstructor?.call("Super WZY") as TestReflect
        println(instance.name)
    }

    //调用第一个构造函数
    fun go14() {
        val instance = clazz.constructors.first().call()
        println(instance.name)
    }

    //方法
    //获取类的全部方法
    fun go03() {
        clazz.functions.forEach {
            println(it)
        }
    }

    //通过declaredFunctions获取本类全部方法
    fun go04() {
        clazz.declaredFunctions.forEach {
            println(it)
        }
    }

    //通过memberExtensionFunctions属性获取全部扩展方法(目前看要在类中声明才有用)
    fun go05() {
        clazz.memberExtensionFunctions.forEach {
            println(it)
        }
    }

    //访问方法
    fun go15() {
        val instance = clazz.createInstance()
        val functions = clazz.declaredFunctions
        functions.forEach {
            if (it.name == "test01") {
                it.isAccessible = true
                it.call(instance, "I am your father.")
            }
        }
    }

    //属性
    //通过declaredMemberProperties获取全部成员属性
    fun go06() {
        clazz.declaredMemberProperties.forEach {
            println(it)
        }
    }

    //通过memberExtensionProperties属性获取该KClass对象的全部扩展属性(要在类中才有效)
    fun go07() {
        clazz.memberExtensionProperties.forEach {
            println(it)
        }
    }

    //访问属性
    @Suppress("UNCHECKED_CAST")
    fun go16() {

        val instance = clazz.createInstance()
        val properties = clazz.declaredMemberProperties

        properties.forEach {
            if (it.name == "age") {
                it as KMutableProperty1<TestReflect, Int>
                it.isAccessible = true
                println(it.get(instance))
                it.set(instance, 33)
                println(it.get(instance))
            }
        }
    }

    //通过annotations属性获取该KClass对象所对应类的全部注解
    fun go08() {
        clazz.annotations.forEach { println(it) }
    }

    //通过nestedClasses属性获取所对应的全部嵌套类
    fun go09() {
        clazz.nestedClasses.forEach { println(it) }
    }

    //通过supertypes属性获取该类的所有父类型
    fun go10() {
        println("父类型为：${clazz.supertypes}")
    }

    //companion 对象
    //获取companion的KClass
    fun go11() {
        println(clazz.companionObject)
    }

}


//定义注解
annotation class TestAnnotationReflect

@TestAnnotationReflect
@Suppress("UNUSED")
class TestReflect(val name: String) {

    companion object {
        const val TAG = "TestReflect"
        fun show() {

        }
    }

    private var age: Int = 0

    constructor() : this("WZY")

    constructor(name: String, age: Int) : this(name) {
        this.age = age
    }

    private fun test01(str: String) {
        println("This is $str")
    }

    fun test02(): String {
        println("This is Test02")
        return "test"
    }

    //嵌套类
    class InnerClass
}

//扩展类
@Suppress("UNUSED")
fun TestReflect.test03() {
    println(" Test03 ")
}

//扩展属性
@Suppress("UNUSED")
val TestReflect.test: String
    get() = "Hello"